package com.jz.netthings.security.utils;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.jz.netthings.bean.AdscmLogEntity;
import com.jz.netthings.bean.system.JyRole;
import com.jz.netthings.bean.system.JyUser;
import com.jz.netthings.core.dao.mysql.AdscmLogMapper;
import com.jz.netthings.security.support.SimpleResponse;
import com.jz.netthings.support.SecurityConstants;
import com.jz.netthings.utils.AdscmBaseUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author yyy
 * @ClassName AdscmSecurityUtils
 * @Description 安全模块工具类
 * @date 2018/7/26 19:07
 */
public class AdscmSecurityUtils {

    private Logger logger = LoggerFactory.getLogger(getClass());
    private static AdscmSecurityUtils securityUtils;

    public static AdscmSecurityUtils getInstance(){
        synchronized (AdscmSecurityUtils.class){
            if (securityUtils == null){
                securityUtils = new AdscmSecurityUtils();
            }
            return securityUtils;
        }
    }

    /**
     * 用户是否具有某个角色
     * @param roleName
     * @param user
     * @return
     */
    public boolean hasRole(String roleName,JyUser user){
        boolean flag = false;

        if (user != null){
            List<JyRole> roles = user.getRoles();
            if (roles != null && roles.size()>0){
                for (JyRole role : roles) {
                    String role_name = role.getRole_name();
                    if (role_name.equals(roleName)){
                        flag = true;
                        break;
                    }
                }
            }
        }

        return  flag;
    }

    /**
     * 设置登录用户的token
     * @param username 用户名
     * @param token token对象
     */
    public void setToken(String username,Token token,RedisTemplate<Object,Token> tokenRedisTemplate) {
        synchronized (this){
            if (AdscmBaseUtils.getInstance().isNotEmpty(username,null) && AdscmBaseUtils.getInstance().isNotEmpty(token,"tokenId")){
                logger.info("将登录成功的用户["+username+"]放到Redis中...");

                 ValueOperations<Object,Token> vo = tokenRedisTemplate.opsForValue();
                 Token lastToken = vo.get(username);
                 if (AdscmBaseUtils.getInstance().isNotEmpty(lastToken,"tokenId")){
                     tokenRedisTemplate.delete(lastToken.getTokenId());
                     tokenRedisTemplate.delete(username);
                 }
                //在没有设置Redis的Value的时候，设置key的失效时间没有用，所以要将失效时间放在最后...
                vo.set(username,token);
                vo.set(token.getTokenId(),token);
                tokenRedisTemplate.expire(username, SecurityConstants.DEFAULT_SIGN_EXPIRE_TIME, TimeUnit.MINUTES);
                tokenRedisTemplate.expire(token.getTokenId(),SecurityConstants.DEFAULT_SIGN_EXPIRE_TIME, TimeUnit.MINUTES);
            }

        }
    }


    public void printMsgByResponse(String statusCode,String desc,HttpServletResponse httpServletResponse, ObjectMapper objectMapper){
        try {
            httpServletResponse.setContentType("application/json;charset=utf-8");
            PrintWriter out = httpServletResponse.getWriter();
            out.write(objectMapper.writeValueAsString(new SimpleResponse(statusCode,desc,null)));
            out.flush();
            out.close();
        }catch (Exception e){
            logger.error("AdscmSecurityUtils.printMsgByResponse 异常",e);
        }
    }

    /**
     * 写登录日志
     * @param user
     * @param ip
     * @param operation
     * @param operParam
     * @param modular
     * @param result
     * @param error
     * @param adscmLogMapper
     */
    public void writeLoginLog(JyUser user, String ip, String operation, String operParam, String modular, String result, String error, AdscmLogMapper adscmLogMapper){
        AdscmLogEntity logEntity = new AdscmLogEntity();
        logEntity.setName(user.getName());
        logEntity.setUserId(user.getId());
        logEntity.setUsername(user.getUsername());
        logEntity.setReqIp(ip);
        logEntity.setOperation(operation);
        logEntity.setOperParam(operParam);
        logEntity.setReqTime(new Date());
        logEntity.setReqModular(modular);
        logEntity.setResult(result);
        logEntity.setError(error);
        adscmLogMapper.insert(logEntity);
    }

}
